
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class Promise {
    #PromiseState = PENDING
    #PromiseResult = undefined
    #eventCallback = []
    constructor(executor){
        const _this = this
        function resolve(data){
            _this.#stateChange(FULFILLED,data)
            _this.#run(_this)
        }
        function reject(reason){
            _this.#stateChange(REJECTED,reason)
            _this.#run(_this)
        }
        //抛出错误的情况
        try {
            executor(resolve,reject)
        } catch (error) {
            reject(error)
        }
    }
    #stateChange(state,result){
        if(this.#PromiseState!==PENDING) return
        this.#PromiseState=state
        this.#PromiseResult=result
    }

    then(onResolved,onRejected){
        return new Promise((resolve,reject)=>{
            if(this.#PromiseState === FULFILLED){
                onResolved(this.#PromiseResult)
            }
            if(this.#PromiseState === REJECTED){
                onRejected(this.#PromiseResult)
            }
            if(this.#PromiseState === PENDING){
                this.#eventCallback.push({
                    onResolved,
                    onRejected,
                    resolve,
                    reject
                })
            }
        })
    }

    #run(_this){
        //判断状态
       if(_this.#PromiseState === PENDING)  return
        while(_this.#eventCallback.length>0){
            const {onResolved , onRejected , resolve , reject } = _this.#eventCallback.shift()
            if(_this.#PromiseState===FULFILLED){
                //判断onResolved是否为一个函数,后续返回值，穿透等
                if(typeof onResolved ==='function'){
                    _this.#oneExecute(onResolved,resolve,reject)
                }else{
                    resolve(_this.#PromiseResult)
                }
            }else{
                if(typeof onRejected ==='function'){
                    _this.#oneExecute(onRejected,resolve,reject)
                }else{
                    reject(_this.#PromiseResult)
                }
            }
        }
    }

    #oneExecute(callback,resolve,reject){
        try {
            const result = callback(this.#PromiseResult)
            if(result instanceof Promise){
                result.then(r=>{
                    resolve(r)
                },s=>{
                    reject(s)
                })
            }else{
                resolve(result)
            }      
        } catch (error) {
           reject(error) 
        }
               
    }
}